/* Reflect.apply(target, thisArgument, argumentsList) 
作用: 通过指定的参数列表发起对目标 (target) 函数的调用。
大白话: 可以调用指定函数,并指定this对象
target - 目标函数。
thisArgument - target 函数调用时绑定的 this 对象。
argumentsList - target 函数调用时传入的实参列表，该参数应该是一个类数组的对象。 
*/

//Reflect.construct 是用构造器创建对象实例，传入构造器参数


//get set 几种写法
var obj = {
    _a: 5,
    set a(value) { this._a = value; },
    get a() { return this._a; },
};

var obj2 = {
    _a: 5,
};
Object.defineProperty(obj2, "a", {
    enumerable: true,
    configurable: true,
    set: function (value) { this._a = value; },
    get: function () { return this._a; },
});



//Proxy
//我发现new创建实例对象的时候，也会触发get函数，被访问的属性是prototype
//至于原因其实我也不太清楚...待解决😵

function myTarget(){}

const proxys = new Proxy(myTarget,{
    //t:target   代理的目标对象
    //p:property 访问/修改的属性
    //r:receiver 接受代理的对象

    get(t,p,r){
        console.log(t,p,r);
        return Reflect.get(...arguments)
    }
})

new proxys();     //[Function: myTarget] prototype [Function: myTarget]
proxys.prototype; //[Function: myTarget] prototype [Function: myTarget]
//其他的捕获器有空再研究，比较使用的应该还有(has、ownKeys、apply)




//想确认下捕获器会不会阻止实例创建  p285
const userList = [];

class User{
    constructor(name){
        this.name_ = name;
        //console.log(name);
    }
}

const proxy = new Proxy(User,{
   //new时候会调用,必须返回一个对象，否则TypeError
   //捕获器不变式: target 必须可以用作构造函数
   //t: 目标对象(在这里必须是可用作构造函数的对象)
   //a: 参数列表
   //n: 最初被调用的构造函数
   construct(t,a,n){
      console.log(t,a,n);

      //可以在这里执行某些操作，例如存储所有new的实例
      const newUser = Reflect.construct(...arguments);
      userList.push(newUser); 

      return newUser; //相当于执行了默认的new proxy()行为 === Reflect.construct(...arguments);
   }
});


new proxy('zjh');
new proxy('newking');
new proxy('newtree');
console.log(userList);
console.log(userList[0].name_);



